﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace MVVMFramework.View
{
    [DefaultProperty("Content")]
    [ContentProperty("Content")]
    [TemplatePart(Name = "PART_ContentHolder", Type = typeof(Border))]
    public class Expander : Control
    {
        private Border PART_ContentHolder;

        #region Ctors

        static Expander()
        {
            Type ownerType = typeof(Expander);
            DefaultStyleKeyProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(ownerType));
        }

        #endregion

        #region Routed Events

        public static readonly RoutedEvent IsExpandedChangedEvent =
            EventManager.RegisterRoutedEvent("IsExpandedChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Expander));

        public event RoutedEventHandler IsExpandedChanged
        {
            add
            {
                AddHandler(IsExpandedChangedEvent, value);
            }
            remove
            {
                RemoveHandler(IsExpandedChangedEvent, value);
            }
        }

        #endregion

        #region DependencyProperties

        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register("Content", typeof(UIElement), typeof(Expander), new PropertyMetadata(null, contentPropertyChangedCallback));

        public UIElement Content
        {
            get
            {
                return (UIElement)GetValue(ContentProperty);
            }
            set
            {
                SetValue(ContentProperty, value);
            }
        }

        private static void contentPropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((Expander)obj).addContentToHolder();
        }

        public static readonly DependencyProperty IsExpandedProperty =
            DependencyProperty.Register("IsExpanded", typeof(bool), typeof(Expander), new PropertyMetadata(false, isExpandedPropertyChangedCallback));

        public bool IsExpanded
        {
            get
            {
                return (bool)GetValue(IsExpandedProperty);
            }
            set
            {
                SetValue(IsExpandedProperty, value);
            }
        }

        private static void isExpandedPropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(IsExpandedChangedEvent);
            ((Expander)obj).RaiseEvent(newEventArgs);
        }

        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof(string), typeof(Expander), new PropertyMetadata(string.Empty));

        public string Header
        {
            get
            {
                return (string)GetValue(HeaderProperty);
            }
            set
            {
                SetValue(HeaderProperty, value);
            }
        }

        public static readonly DependencyProperty ContentHeightProperty =
            DependencyProperty.Register("ContentHeight", typeof(double), typeof(Expander), new PropertyMetadata(double.NaN));

        public double ContentHeight
        {
            get
            {
                return (double)GetValue(ContentHeightProperty);
            }
            set
            {
                SetValue(ContentHeightProperty, value);
            }
        }

        public static readonly DependencyProperty ExpandButtonDirectionProperty =
            DependencyProperty.Register("ExpandButtonDirection", typeof(ExpandDirection), typeof(Expander), new PropertyMetadata(ExpandDirection.Down));

        public ExpandDirection ExpandButtonDirection
        {
            get
            {
                return (ExpandDirection)GetValue(ExpandButtonDirectionProperty);
            }
            set
            {
                SetValue(ExpandButtonDirectionProperty, value);
            }
        }

        public static readonly DependencyProperty ShowExpandButtonProperty =
            DependencyProperty.Register("ShowExpandButton", typeof (bool), typeof (Expander), new PropertyMetadata(true));

        public bool ShowExpandButton
        {
            get
            {
                return (bool) GetValue(ShowExpandButtonProperty);
            }
            set
            {
                SetValue(ShowExpandButtonProperty, value);
            }
        }

        #endregion

        public override void OnApplyTemplate()
        {
            PART_ContentHolder = GetTemplateChild("PART_ContentHolder") as Border;

            addContentToHolder();
            base.OnApplyTemplate();
        }

        private void addContentToHolder()
        {
            if (PART_ContentHolder != null)
                PART_ContentHolder.Child = Content;
        }
    }
}
